/**
 * 
 */
package com.estock.platform.task.support;

import java.util.Date;
import java.util.concurrent.ThreadFactory;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.estock.common.model.task.TaskRun;
import com.estock.common.model.task.enums.TaskRunStatus;
import com.estock.common.util.CommonUtil;
import com.estock.platform.manager.DBManager;

/**
 * @author mango
 *
 */
public abstract class ESJob implements Job {
	
	protected TaskRun taskRun;
	
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		JobDataMap dataMap = context.getJobDetail().getJobDataMap();  
        taskRun = (TaskRun) dataMap.get("taskrun");
		startTaskRun();
		
		// execute job
		executeJob();
		
		finishTaskRun();
	}
	
	protected abstract void executeJob();
	
	private void startTaskRun() {
        taskRun.setStartedDTime(new Date());
        taskRun.setStatus(TaskRunStatus.STARTED.getRunStatus());
        DBManager.getInstance().saveOrUpdate(taskRun);
	}
	
	private void finishTaskRun() {
		taskRun.setFinishedDTime(new Date());
        taskRun.setStatus(TaskRunStatus.FINISHED.getRunStatus());
        DBManager.getInstance().saveOrUpdate(taskRun);
	}
	
	protected void errorTaskRun() {
		taskRun.setFinishedDTime(new Date());
        taskRun.setStatus(TaskRunStatus.ERROR.getRunStatus());
        DBManager.getInstance().saveOrUpdate(taskRun);
	}
	
	public class HandlerThreadFactory implements ThreadFactory {
	    @Override
	    public Thread newThread(Runnable r) {
	        Thread t = new Thread(r);
	        t.setUncaughtExceptionHandler(new ESExceptionHandler());
	        return t;
	    }
	}
	
	class ESExceptionHandler implements Thread.UncaughtExceptionHandler {
	    @Override
	    public void uncaughtException(Thread t, Throwable e) {
	    	if (!CommonUtil.isUnitTest) {
	    		errorTaskRun();
	    	}
	    	System.out.println("Catch uncaughtException in ESExceptionHandler");
	    }
	}
	
}
